/* 
 * File: MultiTouchHandler
 * Created: 13-JUN-2011
 * Author: Colin Gall-McDaid
 * 
 * Description: Touch handler for multi-touch Android devices. These are all
 * devices running Android versions 2.0 and above.
 */
package com.gallsoft.games.framework.impl;

import com.gallsoft.games.framework.Input.TouchEvent;

import android.view.MotionEvent;
import android.view.View;


public class MultiTouchHandler extends BaseHandler {

    boolean[] isTouched = new boolean[20];
    private int[] touchX = new int [20];
    private int[] touchY = new int [20];
    
    /**
     * Constructor. Allows scaling for different screen resolutions.
     * 
     * @param view the Android View
     * @param scaleX x scale adjustment 
     * @param scaleY y scale adjustment
     */
    public MultiTouchHandler(View view, float scaleX, float scaleY) {
        super(view, scaleX, scaleY);
    }

    /**
     * Check if a given pointerid is touching the screen
     * 
     * @param pointer pointer id
     * @return true or false
     */
    public boolean isTouchDown(int pointer) {
        synchronized (this) {
            if (pointer < 0 || pointer >= 20)
                return false;
            else
                return isTouched[pointer];
        }
    }

    /**
     * Get x coord of given pointer pointerid
     * 
     * @param pointer pointer id
     * @return x screen position of pointer
     */
    public int getTouchX(int pointer) {
        synchronized (this) {
            if (pointer < 0 || pointer >= 20)
                return 0;
            else
                return touchX[pointer];
        }
    }

    /**
     * Get y coord of given pointer pointerid
     * 
     * @param pointer pointer id
     * @return y screen position of pointer
     */
    public int getTouchY(int pointer) {
        synchronized (this) {
            if (pointer < 0 || pointer >= 20)
                return 0;
            else
                return touchY[pointer];
        }
    }

    /**
     * Implementation of the OnTouchListener.onTouch method
     * 
     * @param v the Android view
     * @param event the touch event that has occured in the view
     */
    public boolean onTouch(View v, MotionEvent event) {
        synchronized (this) {
            int action = event.getAction() & MotionEvent.ACTION_MASK;
            int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) 
                >> MotionEvent.ACTION_POINTER_ID_SHIFT;            
            int pointerId = event.getPointerId(pointerIndex);
            TouchEvent touchEvent;
            
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_POINTER_DOWN:
                    touchEvent = touchEventPool.newObject();
                    touchEvent.type = TouchEvent.TOUCH_DOWN;
                    touchEvent.pointer = pointerId;
                    touchEvent.x = touchX[pointerId] = (int)(event.getX(pointerIndex) * scaleX);
                    touchEvent.y = touchY[pointerId] = (int)(event.getY(pointerIndex) * scaleY);
                    isTouched[pointerId] = true;
                    touchEventsBuffer.add(touchEvent);
                    break;
                    
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                case MotionEvent.ACTION_CANCEL:
                    touchEvent = touchEventPool.newObject();
                    touchEvent.type = TouchEvent.TOUCH_UP;
                    touchEvent.pointer = pointerId;
                    touchEvent.x = touchX[pointerId] = (int)(event.getX(pointerIndex) * scaleX);
                    touchEvent.y = touchY[pointerId] = (int)(event.getY(pointerIndex) * scaleY);
                    isTouched[pointerId] = true;
                    touchEventsBuffer.add(touchEvent);
                    break;

                case MotionEvent.ACTION_MOVE:
                    int pointerCount = event.getPointerCount();
                    
                    for (int i = 0; i < pointerCount; i++) {
                        pointerIndex = i;
                        pointerId = event.getPointerId(pointerIndex);
                        
                        touchEvent = touchEventPool.newObject();
                        touchEvent.type = TouchEvent.TOUCH_DRAGGED;
                        touchEvent.pointer = pointerId;
                        touchEvent.x = touchX[pointerId] = (int)(event.getX(pointerIndex) * scaleX);
                        touchEvent.y = touchY[pointerId] = (int)(event.getY(pointerIndex) * scaleY);
                        touchEventsBuffer.add(touchEvent);
                    }
                    break;
            }
        }
        
        return true;
    }

}
